package com.asp.aspchain.transaction.controller;

import com.alibaba.fastjson.JSON;
import com.asp.aspchain.core.base.controller.BaseController;
import com.asp.aspchain.core.model.MgrNodeModel;
import com.asp.aspchain.core.service.IMgrNodeService;
import com.asp.aspchain.core.service.IMineringService;
import com.asp.aspchain.core.util.AjaxResult;
import com.asp.aspchain.core.util.BlogUtil;
import com.asp.aspchain.core.util.HttpRequestUtil;
import com.asp.aspchain.core.util.UrlUtil;
import com.asp.aspchain.transaction.constants.ErrorCode;
import com.asp.aspchain.transaction.request.MineringReq;
import com.asp.aspchain.transaction.service.AppMineringService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * 交易接口
 * @author zhongzifeng
 * @date 2018/10/24
 */
@Controller
@RequestMapping("/tranction")
public class AppMinerController extends BaseController {

    private static final Logger logger = Logger.getLogger(AppMinerController.class);

    /**
     * 挖矿节点标识
     */
    private String minerId = "02";

    @Value("${ethereum.url}")
    private String url;

    @Value("${server.port}")
    private String port;

    @Value("${server.context-path}")
    private String context;

    @Autowired
    private AppMineringService appMineringService;

    @Autowired
    private IMineringService iMineringService;

    @Autowired
    private IMgrNodeService iMgrNodeService;


    /**
     * 开始挖矿接口(内部接口）
     * @param json
     * @return
     * @author zhongzifeng
     * @date 2018/10/24
     */
    @RequestMapping(value="/minering",method= RequestMethod.POST)
    @ResponseBody
    public AjaxResult minering(@RequestBody String json){
        logger.info("=============开始挖矿接口开始=============");
        BlogUtil.inlog(json, "", "tranction/minering", "minering", "req");
        //接受前端请求记录内部日志
        AjaxResult ajaxResult = new AjaxResult();
        String reqsp = null;
        String goToNodeIp = null;
        String nativeIp = null;
        try{
            MineringReq req = JSON.parseObject(json, MineringReq.class);
            if(req == null){
                logger.error("挖矿失败，json参数为空");
                return new AjaxResult("1","挖矿失败，json参数为空","");
            }
            checkPayParam(req);
            String hmac = req.getHmac();
            boolean falg = sign(hmac);
            if(!falg){
                logger.info("挖矿失败，验证签名不通过");
                return new AjaxResult("1","挖矿失败，验证签名不通过","");
            }
            Wrapper<MgrNodeModel> wrapper = new EntityWrapper<MgrNodeModel>();
            wrapper.eq("nodeid",req.getNodeid());
            List<MgrNodeModel> nodes = iMgrNodeService.selectList(wrapper);
            if(nodes==null || nodes.size() != 1){
                logger.error("挖矿失败，node参数错误");
                return new AjaxResult("1","挖矿失败，node参数错误","");
            }
            MgrNodeModel node = nodes.get(0);
            String nodeType = node.getNodetype();
            // 检查节点是否有挖矿权限
            if(!nodeType.contains(minerId)){
                logger.error("挖矿失败，node无挖矿权限");
                return new AjaxResult("1","挖矿失败，node无挖矿权限","");
            }
            goToNodeIp = node.getNodeip();

            // 本机管理节点地址
            nativeIp = UrlUtil.subHostName(url,true);
            if(nativeIp.equals(goToNodeIp)){
                // 本机处理
                ajaxResult = appMineringService.minering(json);
                reqsp = JSON.toJSONString(ajaxResult);
            } else {
                // 转发节点
                url = "http://" + goToNodeIp + ":" + port + context + "/tranction" + "/minering";
                reqsp = HttpRequestUtil.postJson(url, json);
            }

            BlogUtil.inlog(reqsp, "", "tranction/minering", "minering", "resp");
        }catch (Exception e) {
            logger.error("minering接口错误："+e.getMessage());
            ajaxResult.setTips("系统内部错误");
            ajaxResult.setMessage("系统内部错误");
            ajaxResult.setStatus(ErrorCode.INTERNAL_ERROR);
        }
        logger.info("=============开始挖矿接口结束=============");
        return ajaxResult;
    }

    /**
     * 停止挖矿接口(内部接口）
     * @param json
     * @return
     * @author zhongzifeng
     * @date 2018/10/24
     */
    @RequestMapping(value="/stopminer",method= RequestMethod.POST)
    @ResponseBody
    public Object stopMiner(@RequestBody String json){
        logger.info("=============停止挖矿接口开始=============");
        BlogUtil.inlog(json, "", "tranction/stopminer", "stopminer", "req");
        //接受前端请求记录内部日志
        AjaxResult ajaxResult = new AjaxResult();
        String reqsp = null;
        String goToNodeIp = null;
        String nativeIp = null;
        try{
            MineringReq req = JSON.parseObject(json, MineringReq.class);
            if(req == null){
                logger.error("停止挖矿失败，json参数为空");
                return new AjaxResult("1","停止挖矿失败，json参数为空","");
            }
            Wrapper<MgrNodeModel> wrapper = new EntityWrapper<MgrNodeModel>();
            wrapper.eq("nodeid",req.getNodeid());
            List<MgrNodeModel> nodes = iMgrNodeService.selectList(wrapper);
            if(nodes==null || nodes.size() != 1){
                logger.error("停止挖矿失败，node参数错误");
                return new AjaxResult("1","停止挖矿失败，node参数错误","");
            }
            MgrNodeModel node = nodes.get(0);
            String nodeType = node.getNodetype();
            // 检查节点是否有挖矿权限
            if(!nodeType.contains(minerId)){
                logger.error("停止挖矿失败，node无挖矿权限");
                return new AjaxResult("1","停止挖矿失败，node无挖矿权限","");
            }
            goToNodeIp = node.getNodeip();

            // 本机管理节点地址
            nativeIp = UrlUtil.subHostName(url,true);
            if(nativeIp.equals(goToNodeIp)){
                // 本机处理
                ajaxResult = appMineringService.stopMiner(json);
                reqsp = JSON.toJSONString(ajaxResult);
            } else {
                // 转发节点
                url = "http://" + goToNodeIp + ":" + port + context + "/tranction" + "/stopminer";
                reqsp = HttpRequestUtil.postJson(url, json);
            }

            BlogUtil.inlog(reqsp, "", "tranction/stopminer", "stopminer", "resp");
        }catch (Exception e) {
            logger.error("stopminer接口错误："+e.getMessage());
            ajaxResult.setTips("系统内部错误");
            ajaxResult.setMessage("系统内部错误");
            ajaxResult.setStatus(ErrorCode.INTERNAL_ERROR);
        }
        logger.info("=============停止挖矿接口结束=============");
        return ajaxResult;
    }
    /**
     * @Description: 入参校验
     * @param: req MineringReq
     * @return:
     * @throws :
     */
    public AjaxResult checkPayParam(MineringReq req) {
        AjaxResult result = new AjaxResult();
        return result;
    }

    /**
     * @Description: 签名校验
     * @param: hmac
     * @return:
     * @throws :
     */

    public boolean sign(String hmac) {
        return true;
    }

}
